package com.firexxx.vp.domain.vp.single;

import com.firexxx.common.domain.AbstractEntity;
import com.firexxx.common.domain.query.QueryRegistry;
import com.firexxx.vp.domain.audio.AudioEntity;
import com.firexxx.vp.domain.audio.query.AudioQueryInterface;
import com.firexxx.vp.domain.mlv.MlvEngineFactory;
import com.firexxx.vp.domain.vp.VoicePrintModel;
import com.firexxx.vp.domain.vp.VoicePrintResourceType;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Where;

import javax.persistence.*;
import javax.validation.constraints.NotNull;

/**
 * @description: TODO
 * @throws:
 * @author: zhuangzhang2
 * @date: 2019/12/19 09:12
 */
@Entity
@Table(name = "single_voiceprint")
@DynamicInsert
@DynamicUpdate
@Where(clause = "is_deleted = false")
@Getter
@NoArgsConstructor(access = AccessLevel.PACKAGE)
@Slf4j
public class SingleVoicePrintEntity extends AbstractEntity {

    @NotNull
    @Column(name = "audio_id")
    private String audioId;

    //在jpa实体中的Transient表示该字段临时使用且不需要缓存，需要被缓存的字段应该放在在cqrs的query service
    @Transient
    private AudioEntity audioEntity;

    @Embedded
    @NotNull
    private VoicePrintModel vpModel;

    public SingleVoicePrintEntity(@NotNull AudioEntity audioEntity) {
        this.audioId = audioEntity.getAudioId();
        this.audioEntity = audioEntity;
    }

    public void extractVoicePrint(VoicePrintResourceType vpResourceType) throws Throwable {
        extractVoicePrintModel(vpResourceType);
        vpModel.extractFeature();
    }

    private void extractVoicePrintModel(VoicePrintResourceType vpResourceType) throws Throwable {
        if (vpModel != null && vpModel.valid()) {
            return;
        }

        rebuildVoicePrintModel(vpResourceType);
    }

    public AudioEntity getAudioEntity() {
        if (audioEntity != null) {
            return audioEntity;
        }

        audioEntity = QueryRegistry.getBean(AudioQueryInterface.class).findByAudioId(audioId);
        return audioEntity;
    }

    private void rebuildVoicePrintModel(VoicePrintResourceType vpResourceType) throws Throwable {
        AudioEntity audioEntity = getAudioEntity();

        String modelStr = MlvEngineFactory.getInstance(vpResourceType)
                .getVoicePrint(audioEntity.getAudioId(), audioEntity.getContent());
        vpModel = new VoicePrintModel(vpResourceType, modelStr);
    }
}